import json
import random

from tkinter import *
from tkinter.ttk import *
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import *
from functools import partial

from game_screen import BigScreen, chunk_array_with_padding
import pygame


class MyConfigApp(Tk):
    """继承Tk，创建自己的桌面应用程序类"""

    def __init__(self):
        """构造函数"""
        super().__init__()
        self.logs = None
        self.init_file = 'assets/game_init.json'
        self.title('控制台')
        self.geometry('600x600+100+100')

        self.the_title = StringVar()
        self.file_path = StringVar()
        self.lun_count = IntVar()
        self.names_per_lun = IntVar()
        self.names_per_line = IntVar()

        self.init_ui()
        self.init_data()

    def init_ui(self):
        """初始化界面"""
        root = self

        root.grid_columnconfigure(0, weight=1)
        root.grid_columnconfigure(1, weight=1)  # 第二列的权重更大，因此它将占据更多空间
        root.grid_columnconfigure(2, weight=1)  # 第二列的权重更大，因此它将占据更多空间
        root.grid_columnconfigure(3, weight=1)  # 第二列的权重更大，因此它将占据更多空间
        root.grid_rowconfigure(6, weight=1)

        labels = ['请输入标题：', '上传名单：', '总轮次：', '每轮选中人数：', '每行显示人数：', ]
        for i in range(len(labels)):
            l = Label(root, text=labels[i])
            l.grid(row=i, column=0, columnspan=1, sticky='w')

        values = [self.the_title, self.file_path, self.lun_count, self.names_per_lun, self.names_per_line]
        for i in range(len(values)):
            if isinstance(values[i], StringVar):
                Entry(root, textvariable=values[i]).grid(row=i, column=1, columnspan=2, sticky="nsew")
            elif isinstance(values[i], IntVar):
                Spinbox(root, textvariable=values[i], from_=1, to=99).grid(row=i, column=1, columnspan=2,
                                                                           sticky="nsew")
            if i == 1:
                Button(root, text='上传', command=partial(self.callback, labels[i])).grid(row=i, column=3, sticky="w")

        buttons = ['继续抽取', '全新开始', '导出结果', '关于']
        for i in range(len(buttons)):
            b = Button(root, text=buttons[i], command=partial(self.callback, buttons[i]))
            b.grid(row=len(labels), column=i, columnspan=1, sticky='w')

        text_box = Text(root)
        text_box.grid(row=1 + len(labels), column=0, columnspan=4, sticky='nsew')
        with open('assets/使用说明.txt', 'r', encoding='utf-8') as f:
            for l in f.readlines():
                text_box.insert('end', l)
        text_box.insert('end',
                        '复杂抽取规则、内定部分名单等更多个性化定制需求请向公众号“东凤莱仪”留言或发邮件到dongfenglaiyi@foxmail.com')
        text_box.config(state='disabled')

    def init_data(self):
        try:
            with open(self.init_file, 'r', encoding='utf-8') as j:
                conf = json.load(j)
                self.the_title.set(conf.get('the_title', ''))
                self.file_path.set(conf.get('file_path', ''))
                self.lun_count.set(conf.get('lun_count', 1))
                self.names_per_lun.set(conf.get('names_per_lun', 1))
                self.names_per_line.set(conf.get('names_per_line', 1))
        except:
            pass

    def save_data(self):
        conf = {'the_title': self.the_title.get(), 'file_path': self.file_path.get(),
                'lun_count': self.lun_count.get(), 'names_per_lun': self.names_per_lun.get(),
                'names_per_line': self.names_per_line.get()}
        with open(self.init_file, "w", encoding='utf-8') as f:
            json.dump(conf, f, ensure_ascii=False, indent=4)
        return conf

    def callback(self, param):
        match param:
            case '关于':
                showinfo(title='Hi',
                         message='v1.1\n如有建议请\n向公众号“东凤莱仪”留言\n或发邮件到dongfenglaiyi@foxmail.com')
                pass
            case '上传名单：':
                print('上传名单：')
                file_path = askopenfilename(filetypes=[('TXT', '*.txt')])
                self.file_path.set(file_path)
            case '继续抽取':
                print('继续抽取')
                self.start_game(False)
            case '导出结果':
                print('导出结果')
                self.output_names()
            case '全新开始':
                print('全新开始')
                self.start_game()
        print(f"Callback called with parameter: {param}")

    def showlog(self, text):
        # self.logs.insert(END, str(text) + "\n")
        # self.logs.update()
        print(text)

    def start_game(self, is_new=True):
        conf = self.save_data()
        if is_new:
            if len(conf['file_path']) <= 0:
                showinfo(title='Hi', message='先选择名单文件！')
            elif conf['lun_count'] == 0:
                showinfo(title='Hi', message='轮次不能小于1！')
            elif conf['names_per_lun'] == 0:
                showinfo(title='Hi', message='每轮人数不能小于1！')
            else:
                App(conf, is_new).on_execute()
        else:
            App(conf, is_new=is_new).on_execute()

    def output_names(self):
        try:
            with open('assets/game_result.json', 'r', encoding='utf-8') as j:
                gamer = json.load(j)

            lines = []
            file = open("抽取名单.txt", 'w', encoding='utf-8')
            for i in range(1, gamer['current_lun']):
                print('第%d轮' % i)
                print('\t'.join(gamer['name_luck'][(i - 1) * gamer['names_per_lun']:(i) * gamer['names_per_lun']]))
                lines.append('第%d轮' % i)
                lines.append('\n')
                lines.append(
                    '\t'.join(gamer['name_luck'][(i - 1) * gamer['names_per_lun']:(i) * gamer['names_per_lun']]))
                lines.append('\n')
            file.writelines(lines)
            file.close()
            showinfo(title='Hi', message='导出成功！')
        except:
            pass
        pass


class App(BigScreen):
    def __init__(self, conf=None, is_new=True):
        super().__init__()
        self.datas = {}
        self.peoples = []
        self.export_file = 'assets/game_result.json'
        if is_new:
            self.init_datas(conf)
        else:
            try:
                with open(self.export_file, 'r', encoding='utf-8') as j:
                    self.datas = json.load(j)
            except:
                showinfo(title='Hi', message='出错了，全新开始吧！')
                self._running = False
                pass

    def init_datas(self, conf):
        self.datas['the_title'] = conf['the_title']
        self.datas['max_lun'] = conf['lun_count']
        self.datas['names_per_lun'] = conf['names_per_lun']
        self.datas['names_per_line'] = conf['names_per_line']
        # self.datas[''] = conf['']
        self.datas['current_lun'] = 0
        self.datas['can_go_on'] = True
        self.datas['name_all'] = []
        try:
            with open(conf['file_path'], 'r', encoding='utf-8') as f:
                for l in f.readlines():
                    people = l.rstrip()
                    self.datas['name_all'].append(people)
        except:
            pass
        self.datas['name_luck'] = []
        self.datas['name_left'] = self.datas['name_all'].copy()
        self.save_data()

    def save_data(self):
        with open(self.export_file, "w", encoding='utf-8') as f:
            json.dump(self.datas, f, ensure_ascii=False, indent=4)

    def get_random_names(self):
        try:
            peoples = random.sample(self.datas['name_left'], self.datas['names_per_lun'])
        except:
            peoples = random.sample(self.datas['name_all'], self.datas['names_per_lun'])
        return peoples

    def save_winner(self, peoples):
        # winners = self.get_random_names()
        for winner in peoples:
            print(winner)
            self.datas['name_luck'].append(winner)
            try:
                self.datas['name_left'].remove(winner)
            except:
                pass
        self.save_data()
        # return winners

    def start_game(self):
        if self.game_paused:
            print('start_game')
            self.game_paused = False
            self.music_unpause()
            if self.datas['current_lun'] == self.datas['max_lun']:
                self.datas['can_go_on'] = False
            else:
                self.datas['current_lun'] += 1

    def pause_game(self):
        if not self.game_paused:
            print('pause_game')
            self.game_paused = True
            self.music_pause()
            if self.datas['can_go_on']:
                self.save_winner(self.peoples)

    def on_other_mouse_down(self, key):
        if key == 1:
            self.start_game()
        elif key == 3:
            self.pause_game()

    def on_other_key_down(self, key):
        if key == pygame.K_SPACE:
            # 开始
            self.start_game()
            pass
        elif key == pygame.K_RETURN:
            # 停
            self.pause_game()
            pass
        else:
            return
        # self.need_update = True

    def on_loop(self):
        if not self.game_paused:
            if self.datas['can_go_on']:
                self.peoples = self.get_random_names()
        pass

    def on_render(self):
        self._display_surf.blit(self.bg, (0, 0))
        self.show_the_texts([self.datas['the_title']], self.conf['header'])
        if self.datas['can_go_on'] and self.datas['current_lun'] > 0:
            self.show_the_texts(['第%d轮' % self.datas['current_lun']], self.conf['lunci'])
        if self.datas['can_go_on']:
            self.show_the_texts(chunk_array_with_padding(self.peoples, self.datas['names_per_line']),
                                self.conf['content'], vertical=True)
        else:
            self.show_the_texts(['Game Over'], self.conf['content'], vertical=True)
        pygame.display.flip()
        pass


if __name__ == '__main__':
    app = MyConfigApp()
    app.mainloop()
